﻿using S7.Net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;

namespace halcon_windows_baoxiansi
{
    public partial class modify : Form
    {
        // 声明SerialPort对象
        private SerialPort _serialPort;
        // 用于标识是否正在接收数据的标志
        private bool _isReceiving = false;
        private RichTextBox richTextBox1;
        private string result1;
        private Plc plc;
        bool plcIsConnect = false;
        public modify(RichTextBox richTextBox1, string result)
        {
            InitializeComponent();
            //LoadAvailablePorts();
            InitializeSerialPort();
            this.richTextBox1 = richTextBox1;
            this.result1 = result;
        }

        private void modify_Load(object sender, EventArgs e)
        {



        }
        #region 串口通信

        // 加载可用的串口列表
        /*private void LoadAvailablePorts()
        {
            //.net8.0新增的功能
            string[] ports = SerialPort.GetPortNames();
            cboPorts.Items.AddRange(ports);

            if (cboPorts.Items.Count > 0)
            {
                cboPorts.SelectedIndex = 0;
            }
        }*/
        private void button1_Click(object sender, EventArgs e)
        {
            if (!_serialPort.IsOpen)
            {
                try
                {
                    /* if (string.IsNullOrEmpty(cboPorts.Text))
                     {
                         MessageBox.Show("请选择一个串口", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                         return;
                     }*/

                    _serialPort.PortName = IniAPI.INIGetStringValue(Directory.GetCurrentDirectory() + "串口.ini", "串口接口", "串口", "1");
                    MessageBox.Show(_serialPort.PortName);
                    _serialPort.Open();
                    //cboPorts.Enabled = false;
                    button2.Enabled = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"打开串口失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                try
                {
                    _serialPort.Close();
                    //cboPorts.Enabled = true;
                    button2.Enabled = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"关闭串口失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void InitializeSerialPort()
        {
            _serialPort = new SerialPort();

            // 设置默认参数(后期改为ini存储)
            _serialPort.BaudRate = 9600;
            _serialPort.DataBits = 8;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Parity = Parity.None;
            _serialPort.Handshake = Handshake.None;

            // 设置读取超时时间
            _serialPort.ReadTimeout = 5000;

            // 绑定数据接收事件
            _serialPort.DataReceived += SerialPort_DataReceived;
        }
        // 数据接收事件处理
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (_isReceiving) return;

            try
            {
                _isReceiving = true;

                SerialPort sp = (SerialPort)sender;
                // 注意：在此事件处理程序中，不宜进行长时间操作，也不要使用ReadTimeout:cite[3]:cite[6]
                int bytesToRead = sp.BytesToRead;
                byte[] buffer = new byte[bytesToRead];
                sp.Read(buffer, 0, bytesToRead); // 此读取操作在该事件中通常会立即完成

                // 处理接收到的数据，例如转换为字符串
                string receivedData = System.Text.Encoding.UTF8.GetString(buffer);

                tools.PrintLog($"接收到数据: {receivedData}", Color.Blue, richTextBox1);
            }
            catch (TimeoutException ex)
            {
                // 超时异常可以忽略，继续等待数据
                tools.PrintLog($"读取数据超时: {ex.Message}", Color.Orange, richTextBox1);
            }
            finally
            {
                _isReceiving = false;
            }
        }
        #endregion

        #region 网口通信

        private void button3_Click(object sender, EventArgs e)
        {
            //通过网口发送数据给服务端 127.0.0.1
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //发送连接请求
            IPAddress iPAddress = IPAddress.Parse(textIP.Text.Trim());
            clientSocket.Connect(iPAddress, 9000);
            //发送数据(转为字节数组)

            int data = clientSocket.Send(System.Text.Encoding.Default.GetBytes(result1));
            if (data > 0)
            {
                MessageBox.Show("发送成功");
            }
            else
            {
                MessageBox.Show("识别成功，发送失败");
            }


        }

        #endregion


        #region PLC通信
        //连接方法
        public void InitPlc(string ip)
        {
            try
            {
                //目标PLC设备的型号 IP地址 机台号/机架号 插槽 
                plc = new Plc(CpuType.S71200, ip, 0, 1);
                plc.Open();
                plcIsConnect = true;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                //调试模式 弹框提示 进行调试
                //发布模式下 把弹窗关闭 防止用户看到
                plcIsConnect = false;
            }
        }

        //连接plc并发送数据
        private void button4_Click(object sender, EventArgs e)
        {
            //计算机发送数据给PLC
            //验证输入文本必须为ip地址 ip地址的正则表达式
            string ipPattern = @"^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$";
            //验证格式是否正确
            //trim是用来去掉前后输入的空格
            bool result = Regex.IsMatch(textBox1.Text.Trim(), ipPattern);
            try
            {
                if (!result)
                {
                    MessageBox.Show("请输入合法的ip地址", "系统消息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (!plcIsConnect)
                {
                    InitPlc(textBox1.Text.Trim());
                    //（1）
                    //1.表示数据的类型 这次传入的参数是数据块
                    //2.设置为1 表示为哪个数据块 1表示DB1
                    //3.代表从上个参数选择的数据块中的起始数据位 
                    //4.可以是任意数据类型
                    //发送的数据为int类型的话 占用4个字节
                    //plc.Write(DataType.DataBlock, 1, 0, 456);

                    //发送的数据是浮点数类型 float占4个 double占8个
                    //plc.Write(DataType.DataBlock, 2, 0, 3.14);

                    //发送的数据是byte 1个字节 无符号
                    byte a = 255;
                    //plc.Write(DataType.DataBlock, 2, 0, a);

                    //发送的数据是字符串 长度可以算 汉字是俩 字母是1
                    string s = "豫A7A7E7";
                    byte[] bytes1 = System.Text.Encoding.Default.GetBytes(s);
                    plc.Write(DataType.DataBlock, 1, 0, result1);


                    //（2）
                    //1.块地址 D表示整形 8表示从第8位开始写
                    //2.写入的值
                    //plc.Write("DB1.DBD8",123);
                    MessageBox.Show("数据发送成功");

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (plc != null)
                    plc.Close();
                plcIsConnect= false;
            }

            //接收数据


        }
        #endregion



        private void button5_Click(object sender, EventArgs e)
        {
            //计算机发送数据给PLC
            //验证输入文本必须为ip地址 ip地址的正则表达式
            string ipPattern = @"^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$";
            //验证格式是否正确
            //trim是用来去掉前后输入的空格
            bool result = Regex.IsMatch(textBox1.Text.Trim(), ipPattern);
            try
            {
                if (!result)
                {
                    MessageBox.Show("请输入合法的ip地址", "系统消息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                //计算机从PLC设备读取数据
                if (!plcIsConnect)
                {
                    InitPlc(textBox1.Text.Trim());

                    //读取第一种方式
                    //DInt为32位 int为16位 plc和c#不一样
                    //textBox2.Text = ((int[])plc.Read(DataType.DataBlock, 1, 0, VarType.DInt, 4))[0].ToString();
                    string plcReadData = plc.Read(DataType.DataBlock, 1, 0, VarType.String, 50).ToString();
                    //第二种
                    //textBox2.Text = plc.Read("DB1.DBB20").ToString();

                   /* // 读取DB1，偏移0，长度为20字节
                    byte[] buffer = (byte[])plc.Read(DataType.DataBlock, 1, 0, VarType.Byte, 20);

                    // S7字符串前两个字节分别是最大长度和当前长度
                    int maxLen = buffer[0];
                    int curLen = buffer[1];

                    // 提取实际字符串内容
                    string plcString = Encoding.ASCII.GetString(buffer, 2, curLen);

                    // 显示或使用
                    textBox2.Text = plcString;*/
                   textBox2.Text = plcReadData;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (plc != null)
                    plc.Close();
            }
        }
    }
}

